#pragma once
// 报文处理，序列化与反序列化

//#include <jsoncpp/json/json.h>
#include "Comm.hpp"
///////////////////////报文协议////////////////////////////////////////////////////
#define SEP "#" // 区分报文与报文
#define SEP_LEN strlen(SEP)
#define SPACE "_" // 区分报文中的每个内容
#define SPACE_LEN strlen(SPACE)
//////////////////////////////////////////////////////////////////////////////////

// 此函数是提取完整报文的
void DeCode(std::string &buffer, std::vector<std::string> *out)
{
    while (true)
    {
        auto pos = buffer.find(SEP);
        if (pos == std::string::npos)
        {
            break;
        }
        std::string message = buffer.substr(0, pos); // 将完整报文切出
        buffer.erase(0, pos + SEP_LEN);              // 从缓冲区去除
        out->push_back(message);
    }
}
// 此函数是将报文增加分隔符
std::string EnCode( std::string &s)
{
    return s + SEP;
}
// 此类为报文请求
class Request
{
public:
    // 序列化
    std::string Serialize()
    {
        std::string s;
        s = std::to_string(_mode);
        s += SPACE;
        s += std::to_string(_decision);
        s += SPACE;
        s += std::to_string(_point_x);
        s += SPACE;
        s += std::to_string(_point_y);
        return s;
        // Json::Value root;
        // root["mode"] = _mode;
        // root["decision"] = _decision;
        // root["x"] = _point_x;
        // root["y"] = _point_y;
        // Json::FastWriter writer;
        // return writer.write(root);
    }
    // // 反序列化
    bool Deserialize(const std::string &s) // 字符串变为数据类型
    {
        std::size_t pos = s.find(SPACE);
        if (pos == std::string::npos)
            return false;
        _mode = std::atoi(s.substr(0, pos).c_str());
        pos += SPACE_LEN;
        int newpos = s.find(SPACE, pos);
        if (newpos == std::string::npos)
            return false;
        _decision = std::atoi(s.substr(pos, newpos).c_str());
        pos = newpos + SPACE_LEN;
        newpos = s.find(SPACE, pos);
        if (newpos == std::string::npos)
            return false;
        _point_x = std::atoi(s.substr(pos, newpos).c_str());
        pos = newpos + SPACE_LEN;
        if (pos >= s.size())
            return false;
        _point_y = std::atoi(s.substr(pos).c_str());
        return true;

        // Json::Value root;
        // Json::Reader reader;
        // reader.parse(s, root);
        // _mode = root["mode"].asInt();
        // _decision = root["decision"].asInt();
        // _point_x = root["x"].asInt();
        // _point_y = root["y"].asInt();
        // return true;
    }

    Request() {}
    Request(int mode, int decision, int point_x, int point_y)
        : _mode(mode),
          _decision(decision),
          _point_x(point_x),
          _point_y(point_y)
    {
    }
    ~Request() {}

public:
    int _mode;
    int _decision;
    int _point_x;
    int _point_y;
};
// 此类为报文响应
class Response
{
public:
    std::string Serialize()
    {
        std::string s;
        s = std::to_string(_mode);
        s += SPACE;
        s += std::to_string(_res);
        s += SPACE;
        s += _expression;
        return s;
        // Json::Value root;
        // root["mode"] = _mode;
        // root["res"] = _res;
        // root["exp"] = _expression;
        // Json::FastWriter writer;
        // return writer.write(root);
    }
    bool Deserialize(const std::string &s) // 字符串变为数据类型
    {
        std::size_t pos = s.find(SPACE);
        if (pos == std::string::npos)
            return false;
        _mode = std::atoi(s.substr(0, pos).c_str());
        pos += SPACE_LEN;
        int newpos = s.find(SPACE, pos);
        if (newpos == std::string::npos)
            return false;
        _res = std::atoi(s.substr(pos, newpos).c_str());
        pos = newpos + SPACE_LEN;
        if (pos >= s.size())
            return false;
        _expression = s.substr(pos);
        return true;
        // Json::Value root;
        // Json::Reader reader;
        // reader.parse(s, root);
        // _mode = root["mode"].asInt();
        // _res = root["res"].asInt();
        // _expression = root["exp"].asCString();
        // return true;
    }

    Response() {}
    Response(int mode, int res, std::string expression)
        : _mode(mode), _res(res), _expression(expression)
    {
    }
    ~Response()
    {
    }

public:
    int _mode = 0;
    int _res = 0;
    std::string _expression;
};